/**
 * ChartData.java
 */
package com.pluginsacceptor.plugin.chart.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.pluginsacceptor.utils.CommunicationUtils;

/**
 * The class contains current chart data and ui state
 */
public class BarChartData implements ChartData {

    /** Chart title */
    private final List<TitleItem> title = new ArrayList<TitleItem>();

    /** Chart paint data values */
    private final List<CellItem> cells = new ArrayList<CellItem>();

    /**The list of using column */
    private final List<Integer> rows = new ArrayList<Integer>();

    /** */
    private Integer titleCol;

    @Override
    public boolean isTitle(final int colItem) {
        if (this.titleCol == null && this.rows.isEmpty()) {
            this.titleCol = colItem;
        }

        return this.titleCol == colItem;
    }

    @Override
    public void clean() {
        this.title.clear();
        this.cells.clear();
        this.rows.clear();
        this.titleCol = null;
    }

    @Override
    public void changeDataItem(
        final Double dataItem,
        final Integer rowItem,
        final Integer colItem,
        final boolean isUpdate
    ) {
        if (isUpdate) {
            final CellItem cellItem = getCell(rowItem, colItem);
            if (cellItem != null) {
                cellItem.setDataItem(dataItem);
            }
        } else {
            if (!this.rows.contains(rowItem)) {
                this.rows.add(rowItem);
                Collections.sort(this.rows);
            }
            this.cells.add(new CellItem(dataItem, rowItem, colItem));
        }
    }

    @Override
    public void changeTileItem(
        final String titleItem,
        final Integer rowItem,
        final boolean isUpdate
    ) {
        if (isUpdate) {
            final TitleItem item = getTitleCell(rowItem);
            if (item != null) {
                item.setDataItem(titleItem);
            }
        } else {
            this.title.add(new TitleItem(titleItem, rowItem));
        }
    }

    @Override
    public List<Double> getData(final int rowNum) {
        final List<Double> date = new ArrayList<Double>();

        final Integer row = this.rows.get(rowNum);
        for (final CellItem item : this.cells) {
            if (item.getRowItem() == row) {
                date.add(item.getDataItem());
            }
        }
        return date;
    }


    @Override
    public int getNumberDataColumn() {
        return this.rows.size();
    }


    @Override
    public List<String> getTitle() {
        final List<String> date = new ArrayList<String>();

        for (final TitleItem item : this.title) {
            date.add(item.getDataItem());
        }
        return date;
    }

    /**
     * @param row the current row
     * @param col the current column
     * @return {@link CellItem} if cell with current row and column already exist,
     * otherwise null
     */
    private CellItem getCell(final Integer row, final Integer col) {
        CellItem result = null;
        for (final CellItem cellItem : this.cells) {
            if (cellItem.getColItem() == col && cellItem.getRowItem() == row) {
                result = cellItem;
                break;
            }
        }

        return result;
    }

    /**
     * @param row the current row
     * @param col the current column
     * @return {@link TitleItem} if title with current row already exist, otherwise null
     */
    private TitleItem getTitleCell(final Integer row) {
        TitleItem result = null;
        for (final TitleItem item : this.title) {
            if (item.getRowItem() == row) {
                result = item;
                break;
            }
        }

        return result;
    }


    @Override
    public String getAffectedCell() {

        final StringBuilder builder = new StringBuilder();
        if (this.titleCol != null) {
            builder.append('$').append(CommunicationUtils.getColumnName(this.titleCol))
                .append('$').append(this.title.get(0).getRowItem() + 1);

            if (!this.cells.isEmpty()) {
                final CellItem lastCell = this.cells.get(this.cells.size() - 1);
                builder.append(":$")
                    .append(CommunicationUtils.getColumnName(lastCell.getColItem()))
                    .append('$').append(lastCell.getRowItem() + 1);
            }
        } else {
            builder.append("[]");
        }
        return builder.toString();
    }

    @Override
    public List<String> getUsingDataCell() {

        final List<String> data = new ArrayList<String>();

        if (this.titleCol != null) {
            for (final TitleItem item : title) {
                data.add(
                    CommunicationUtils.cellDataToString(
                        item.getRowItem(),
                        this.titleCol,
                        item.getDataItem()
                    )
                );
            }

            for (final CellItem item : cells) {
                data.add(
                    CommunicationUtils.cellDataToString(
                        item.getRowItem().intValue(),
                        item.getColItem().intValue(),
                        String.valueOf(item.getDataItem())
                    )
                );
            }
        }

        return data;
    }


    @Override
    public String toString() {
        return "BarChartData [title=" + title + ", cells=" + cells + ", columns=" + rows
                + ", titleCol=" + titleCol + "]";
    }
}

